package com.ruoyi.cinema.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.cinema.BO.GoodsBuyedMsgBo;
import com.ruoyi.cinema.BO.YzOrderInfoReqBO;
import com.ruoyi.order.BO.GoodsOrderFinishMsgBO;
import com.ruoyi.cinema.DTO.AccountInfoYzDTO;
import com.ruoyi.cinema.DTO.TemplateDataDTO;
import com.ruoyi.cinema.DTO.WechatSubscribeRequest;
import com.ruoyi.cinema.domain.Customer;
import com.ruoyi.cinema.mapper.CustomerMapper;
import com.ruoyi.cinema.service.ICustomerService;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.WechatConstants;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.order.BO.GoodsOrderFinishMsgBO;
import com.ruoyi.utils.WechatUtils;
import com.ruoyi.utils.YzResult;
import com.ruoyi.utils.YzUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 会员名称Service业务层处理
 *
 * @author HHAOYU
 * @date 2020-12-08
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService  {

    private final Logger logger = LoggerFactory.getLogger(CustomerServiceImpl.class);

    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private RedisCache redisCache;

    /**
     * 查询会员名称
     *
     * @param id 会员名称ID
     * @return 会员名称
     */
    @Override
    public Customer selectCustomerById(Long id)
    {
        return customerMapper.selectCustomerById(id);
    }

    /**
     * 查询会员名称列表
     *
     * @param customer 会员名称
     * @return 会员名称
     */
    @Override
    public List<Customer> selectCustomerList(Customer customer)
    {
        return customerMapper.selectCustomerList(customer);
    }

    /**
     * 新增会员名称
     *
     * @param customer 会员名称
     * @return 结果
     */
    @Override
    public int insertCustomer(Customer customer)
    {
        customer.setCreateTime(DateUtils.getNowDate());
        return customerMapper.insertCustomer(customer);
    }

    /**
     * 修改会员名称
     *
     * @param customer 会员名称
     * @return 结果
     */
    @Override
    public int updateCustomer(Customer customer)
    {
        customer.setUpdateTime(DateUtils.getNowDate());
        return customerMapper.updateCustomer(customer);
    }

    /**
     * 批量删除会员名称
     *
     * @param ids 需要删除的会员名称ID
     * @return 结果
     */
    @Override
    public int deleteCustomerByIds(Long[] ids)
    {
        return customerMapper.deleteCustomerByIds(ids);
    }

    /**
     * 删除会员名称信息
     *
     * @param id 会员名称ID
     * @return 结果
     */
    @Override
    public int deleteCustomerById(Long id)
    {
        return customerMapper.deleteCustomerById(id);
    }


    @Override
    public Customer bindYZ(Customer customer) {

        Map<String,String> accessMap =  YzUtils.getAccessToken(getRefreshToken(),customer.getPhone());
        if(null != accessMap){
            redisCache.setCacheObject(customer.getId()+Constants.YZ_ACCESS_TOKEN,accessMap.get("accessToken"),15,TimeUnit.MINUTES);
            customer.setAccountId(accessMap.get("accountId"));
            YzResult<AccountInfoYzDTO> accountInfoRet = YzUtils.getAccountInfo(accessMap.get("accessToken"));
            if(accountInfoRet.getResultCode().equals(200) && accountInfoRet.getData().getBizCode().equals("SUCCESS")){
                AccountInfoYzDTO accountInfoYzDTO = accountInfoRet.getData().getBizData();
                BeanUtil.copyProperties(accountInfoYzDTO,customer,"id");
                customerMapper.updateCustomer(customer);
                return customer;
            }
        }
        return null;
    }

    private String getRefreshToken(){
       String refreshToken = redisCache.getCacheObject(Constants.YZ_REFRESH_TOKEN);
       if(StringUtils.isEmpty(refreshToken)){
           YzUtils.getRefreshToken();
           int i = 0;
           while (StringUtils.isEmpty(refreshToken) && i < 5){
               i++;
               refreshToken = redisCache.getCacheObject(Constants.YZ_REFRESH_TOKEN);
               try {
                   TimeUnit.SECONDS.sleep(1);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
           return refreshToken;
       }
       return refreshToken;
    }

    @Override
    public String getAccessToken(Long id, String mobile){
        String accessToken = redisCache.getCacheObject(id+ Constants.YZ_ACCESS_TOKEN);
        if(null == accessToken){
           Map<String,String> accessMap =  YzUtils.getAccessToken(getRefreshToken(),mobile);
           if(null != accessMap && accessMap.containsKey("accessToken")){
               redisCache.setCacheObject(id+Constants.YZ_ACCESS_TOKEN,accessMap.get("accessToken"),15,TimeUnit.MINUTES);
               return accessMap.get("accessToken");
           }else {
               return "";
           }
        }
        return accessToken;

    }

    @Override
    public String getAccessToken(Long id){
        Customer customer = selectCustomerById(id);
        if(null == customer){
            return null;
        }
        return getAccessToken(customer.getId(),customer.getPhone());
    }
    @Override
    public String getWechatAccessToken(){
       String wechatToken =  redisCache.getCacheObject(WechatConstants.WEIXIN_TOKEN_PRE);
       if(null != wechatToken){
           return wechatToken;
       }
       String newWechatToken = WechatUtils.getWechatAccessToken();
       if(null != newWechatToken){
           redisCache.setCacheObject(WechatConstants.WEIXIN_TOKEN_PRE,newWechatToken,80,TimeUnit.MINUTES);
           return newWechatToken;
       }
       return null;
    }

    public void sendGoodsBuyMessage(GoodsBuyedMsgBo gumb){
        String token = getWechatAccessToken();
        if(StringUtils.isEmpty(token)){
            logger.error(" 发送订阅消息 获取微信token 失败");
            return;
        }
        WechatSubscribeRequest request = new WechatSubscribeRequest();
        request.setTouser(gumb.getOpenId());
        request.setTemplate_id("7Xxtj6cGcO_LkQj4D1KGortDoZj4EUxL-vnDn6dxIUE");
        Map<String,  TemplateDataDTO> data = new HashMap<>(5);
        data.put("character_string1",new TemplateDataDTO(gumb.getFulfillCode()));
        data.put("time2",new TemplateDataDTO(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm",gumb.getUpdateTime())));
        data.put("time3",new TemplateDataDTO(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm",gumb.getFulfillTime())));
        data.put("thing4",new TemplateDataDTO("到店消费"));
        data.put("thing5",new TemplateDataDTO("影城小吃"));
        request.setData(data);
        WechatUtils.sendWeChatSubscribeMessage(token,request);
        Long time = gumb.getFulfillTime().getTime();
        Double score = time.doubleValue();
        YzOrderInfoReqBO yzOrderInfoReqBO = new YzOrderInfoReqBO(gumb);
        String value = JSONObject.toJSONString(yzOrderInfoReqBO);
        redisCache.setZSet(WechatConstants.WEIXIN_MESSAGE_ORDER_FINISH_PRE,value,score);
    }

    public void sendGoodsCanGetMessage(GoodsOrderFinishMsgBO gofb){
        String token = getWechatAccessToken();
        if(StringUtils.isEmpty(token)){
            logger.error(" 发送订阅消息 获取微信token 失败");
            return;
        }
        WechatSubscribeRequest request = new WechatSubscribeRequest();
        request.setTouser(gofb.getOpenId());
        request.setTemplate_id("546PhTUdFth7nJLMkdMN1BmAGFoQFAMRu9dMYY6z7M8");
        Map<String,  TemplateDataDTO> data = new HashMap<>(5);
        data.put("thing7",new TemplateDataDTO(gofb.getCinemaName()));
        data.put("character_string1", new TemplateDataDTO(gofb.getFulfillCode()));
        data.put("thing2",new TemplateDataDTO("影城小吃"));
        data.put("thing5",new TemplateDataDTO("您的订单已到取餐时间，请前往取餐区取餐"));
        data.put("time3",new TemplateDataDTO(DateUtils.parseDateToStr("yyyy-MM-dd HH:mm",gofb.getUpdateTime())));
        request.setData(data);
        WechatUtils.sendWeChatSubscribeMessage(token,request);
    }
}

